import json

from sanic import response

from config.LoadConfig import get_config
from utils.EncryptUtil import EncryptUtil
from utils.SqliteExecutor import sqlite_execute_sql, sqlite_execute_query, sqlite_batch_insert_data
from datetime import datetime
from config.ServerApp import app
from service.OcrHandlerService import classfy_by_ocr, ocr_classfy
from utils.DataUtil import *
from utils.FileUtils import *
from service.QrCodeHandlerService import *
from service.clip_classify_service import *
from utils.HttpRequest import do_request,do_query_request
from utils.NetworkUtils import get_ip
import time
from utils.FileWriteUtils import json_lines_to_list

# from service.ClassfyVlModelHandlerService import remap_to_db_categories


__system_conf = get_config("system")
__process_type = __system_conf.get("server_name","ai-img-classify-server")
__biz_source = __system_conf.get("biz_source","NONE")
__model_type = __system_conf.get("model_type","")


encrypt_key = (__system_conf['encrypt_key'] if 'encrypt_key' in __system_conf else 'pinghang@1232025').encode('utf-8')

__proces_task_isnert_sql = '''
                           INSERT INTO process_task_record (batch_id, gmt_create, gmt_modify, task_status, remark, \
                                                            priority, ext_params, file_system_type, biz_type)
                           VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) \
                           '''
__proces_task_log_insert_sql = '''
                               INSERT INTO process_task_record_log (task_record_id, unique_id, process_target, \
                                                                    gmt_create, gmt_modify, process_status, remark)
                               VALUES (?, ?, ?, ?, ?, ?, ?) \
                               '''


def image_classify_route(local_img_path: str, source_img_url: str, uniqueId: str,kwargs: dict = {}):
    _prompt_code = kwargs.get('vlPromptCode', __system_conf.get('vl_classify_prompt_code', "secondary_classify"))
    _format = kwargs.get('vlFormat', __system_conf.get('vl_classify_format', "to_json"))
    if __model_type == "vl":# 只有舟山是vl，其余都是mix混合模型逻辑
        from service.ClassfyVlModelHandlerService import vl_classify_format
        result = vl_classify_format(source_img_url, kwargs.get('prompt', ''), prompt_code=_prompt_code,
                                    format=kwargs.get('format', _format))
        if isinstance(result, dict):
            result.update({"imageUrl": source_img_url, "uniqueId": uniqueId})
        return {
            "extInfo": "",
            "msg": "",
            "code": 200,
            "data": result
        }
    else:
        return image_classfy(local_img_path, source_img_url, uniqueId)


def image_classfy(local_img_path: str, source_img_url: str, uniqueId: str):
    """
    :param source_img_url: 图片原路径
    :param local_img_path: 下载到本地得图片url
    :param uniqueId: 图片对应唯一id

    类目汇总：
    人物：男人、女人、小孩儿、青年、老年、人脸
    卡证：身份证、银行卡、护照、驾驶证、营业执照、户口本
    文档：票据、支付截图、转账截图、短信验证码截图、红头公章文件、聊天截图、快递单、名片、股票截图、体育彩票截图、六合彩截图、航班截图、行程订票截图
    二维条形码：收付款码、条形码、广告二维码
    """
    try:
        resutl = []
        clip_result = clip_classify(local_img_path)
        # max_clip_confidence = max(clip_result, key=lambda x: float(x['confidence']))
        if clip_result:
            resutl += clip_result

        # 二维码分类
        start_time = time.time()
        qrcode_classfy, qr_text = classfy_by_qrcode(local_img_path)
        end_time = time.time()
        cost = end_time - start_time
        app.ctx.logger.info(f'==================>qrcode分类耗时：{cost}')
        print(f'==================>qrcode分类耗时：{cost}')
        if qrcode_classfy is not None and len(qrcode_classfy) > 0:
            resutl += qrcode_classfy
            # return build_success_result(source_img_url,uniqueId,resutl, ocr_result=ocr_result,qr_result=qr_text)
        model_type = __system_conf.get("classfy_model_type", "classfy_model")

        if "vl_model" in model_type:
            start_time = time.time()
            from service.ClassfyVlModelHandlerService import classfy_by_model
            model_classfy = classfy_by_model(img_url=source_img_url)
            end_time = time.time()
            cost = end_time - start_time
            app.ctx.logger.info(f'===============》VL分类耗时：{cost}')
            if model_classfy is not None and len(model_classfy) > 0 and len(model_classfy.get('result', [])):
                vl_result = model_classfy.get('result', [])
                resutl += vl_result
                content_summary = model_classfy.get("contentSummary", "")
                ocr_result = model_classfy.get("ocrResult", "")
                ocr_classfy_result = ocr_classfy(ocr_result)
                if len(ocr_classfy_result) > 0:
                    resutl += ocr_classfy_result
                return build_success_result(source_img_url, uniqueId, resutl, ocr_result=ocr_result,
                                            content_summary=content_summary, qr_result=qr_text)
        # OCR分类 - 已启用
        ## vl模型包括ocr 不重复调用
        ocr_result = ""
        ocr_classfy_result = []
        
        if "vl_model" not in model_type:
            # 仅在不使用VL模型时执行OCR分类
            start_time = time.time()
            ocr_classfy_result, ocr_result = classfy_by_ocr(local_img_path)
            end_time = time.time()
            cost = end_time - start_time
            app.ctx.logger.info(f'===============》OCR分类耗时：{cost}')
            print(f'===============》OCR分类耗时：{cost}')
            
            if ocr_classfy_result is not None and len(ocr_classfy_result) > 0:
                resutl += ocr_classfy_result

        # 模型分类
        if "classfy_model" in model_type:
            from service.ClassfyModelHandlerService import classfy_by_model
            model_classfy = classfy_by_model(local_img_path)
            if model_classfy is not None and len(model_classfy) > 0:
                resutl += model_classfy
                return build_success_result(source_img_url, uniqueId, resutl, ocr_result=ocr_result, qr_result=qr_text)

        # 无归属类目
        no_classfy = resutl
        if len(no_classfy) == 0:
            no_classfy.append(build_classfy_obj('其他', '其他', 1.0))

        return build_success_result(source_img_url, uniqueId, no_classfy, ocr_result=ocr_result, qr_result=qr_text)

    except Exception as e:
        raise e


def batch_images_classfy(params: dict):
    """
    :param params: 图片路径
    批量图片分类识别
    """
    try:
        batch_id = params["batchId"]
        q_success, query_list = do_query_request("POST", "/task/query", json={"taskId": batch_id})
        if query_list is not  None and len(query_list)> 0:
            response_data = {
                "extInfo": "处理任务已存在，请勿重复提交！",
                "code": 500,
                "msg": "处理任务已存在，请勿重复提交！",
                "data": None
            }
            return response.json(response_data)
        # 生成处理任务
        ip=get_ip()
        task_name=f"{__biz_source}-{ip}-图片分类任务"
        p_json={"taskName": task_name,"taskId": batch_id,"scene": __process_type,"description": '图片分类任务',"status": 'INIT',"creator": 'system',
              "modifier": 'system',"priority": 5,"taskParam": params}
        i_success,data = do_request("POST", "/task/insert", json=p_json)
        if i_success:
            response_data = {
                    "extInfo": "数据已提交处理，请耐心等待！",
                    "code": 200,
                    "msg": "数据已提交处理，请耐心等待！",
                    "data": None
            }
        else:
            response_data = {
                    "extInfo": "数据提交失败！",
                    "code": 500,
                    "msg": "数据提交失败！",
                    "data": None
            }
        return response.json(response_data)
    except Exception as e:
        raise e


def get_img_classfy_result(batch_id: str):
    """
    获取图片classfy识别结果
    """
    try:
        q_success,record_data=do_query_request("POST", "/task/query", json={"taskId":batch_id})
        if record_data  and len(record_data) > 0:
            record_data = record_data[0]
            if record_data['status'] == 'INIT' or record_data['status'] == 'PROCESSING':
                # 处理中结果
                return response.json(build_success_msg_result("数据已提交处理，请耐心等待！"))
            elif record_data['status'] == 'FINISH':
                # 处理成功结果
                success_file_path=record_data["taskSuccessResult"]
                ocr_rows_result=""
                with open(success_file_path, 'r', encoding='utf-8') as f:
                   ocr_rows_result= f.read()
                classfy_result_list=  json_lines_to_list(ocr_rows_result)
                return response.json(build_batch_success_result(classfy_result_list))
            elif record_data['status'] == 'ERROR':
                taskFailResult=record_data['taskFailResult']
                fail_result=""
                with open(taskFailResult, 'r', encoding='utf-8') as f:
                   fail_result= f.read()
                return response.json(build_fail_result(None,  f"处理失败,{fail_result}"))
        else:
            return response.json(build_fail_result(None, f"批次：{batch_id}任务不存在！"))
    except Exception as e:
        raise e


def batch_images_ocr_commit(params: dict):
    """
    批量图片OCR提交（异步）
    创建任务后由定时器/工作线程处理，查询使用 get_ocr_only_result
    """
    try:
        batch_id = params["batchId"]
        q_success, query_list = do_query_request("POST", "/task/query", json={"taskId": batch_id})
        if query_list is not  None and len(query_list)> 0:
            response_data = {
                "extInfo": "处理任务已存在，请勿重复提交！",
                "code": 500,
                "msg": "处理任务已存在，请勿重复提交！",
                "data": None
            }
            return response.json(response_data)
        ip = get_ip()
        task_name = f"{__biz_source}-{ip}-图片OCR任务"
        # 确保仅OCR流程标记
        if isinstance(params, dict):
            params["processType"] = "ocr_only"
        p_json = {
            "taskName": task_name,
            "taskId": batch_id,
            "scene": __process_type,
            "description": '图片OCR任务',
            "status": 'INIT',
            "creator": 'system',
            "modifier": 'system',
            "priority": 5,
            "taskParam": params
        }
        i_success, data = do_request("POST", "/task/insert", json=p_json)
        if i_success:
            response_data = {
                "extInfo": "数据已提交处理，请耐心等待！",
                "code": 200,
                "msg": "数据已提交处理，请耐心等待！",
                "data": None
            }
        else:
            response_data = {
                "extInfo": "数据提交失败！",
                "code": 500,
                "msg": "数据提交失败！",
                "data": None
            }
        return response.json(response_data)
    except Exception as e:
        raise e


def get_ocr_only_result(batch_id: str):
    """
    获取批量OCR文本结果（仅返回OCR文本，不包含分类）。
    复用任务框架与结果文件：当任务完成时，从 success_results.txt 读取每行JSON，抽取 data.ocrResult。
    """
    try:
        q_success, record_data = do_query_request("POST", "/task/query", json={"taskId": batch_id})
        if record_data and len(record_data) > 0:
            record = record_data[0]
            status = record.get('status')
            if status in ('INIT', 'PROCESSING'):
                return response.json(build_success_msg_result("数据已提交处理，请耐心等待！"))
            if status == 'FINISH':
                success_file_path = record.get("taskSuccessResult", "")
                if not success_file_path:
                    return response.json(build_fail_result(None, "处理成功但未找到结果文件！"))
                ocr_only_list = []
                with open(success_file_path, 'r', encoding='utf-8') as f:
                    for line in f:
                        line = line.strip()
                        if not line:
                            continue
                        try:
                            row = json.loads(line)
                        except Exception:
                            continue
                        data_obj = row.get('classfy_result', {})
                        image_url = row.get('image_url', '')
                        unique_id = row.get('unique_id', '')
                        ocr_text = ''
                        if isinstance(data_obj, dict):
                            ocr_text = data_obj.get('ocrResult', '')
                        ocr_only_list.append({
                            "imageUrl": image_url,
                            "uniqueId": unique_id,
                            "ocrText": ocr_text
                        })
                return response.json(build_batch_success_result(ocr_only_list))
            if status == 'ERROR':
                fail_path = record.get('taskFailResult', '')
                fail_result = ''
                if fail_path:
                    with open(fail_path, 'r', encoding='utf-8') as f:
                        fail_result = f.read()
                return response.json(build_fail_result(None, f"处理失败,{fail_result}"))
        return response.json(build_fail_result(None, f"批次：{batch_id}任务不存在！"))
    except Exception as e:
        raise e